package CamposDePotencial;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Properties;

import javax.vecmath.Point3d;

import monitor.ManagerObjetos;

import comunicacion.Conector;
import comunicacion.ParametrosEntorno;
import estrategia.ParametrosGlobales;
import estrategia.Predictor;
import estrategia.Utiles;


public class FabricaPotenciales {
	
	private HashMap<Integer, ArrayList<CampoPotencial>> campos;
	private ArrayList<Integer> objetos;
	private Utiles utiles;
	private Predictor predictor;
	
	private Objetivo objetivo;
	
	
	public enum TIPOS_CAMPOS {
		SEMIPLANO, CIRCULAR, UNIFORME
	};
	
	
	public enum PAREDES {
		ARRIBA, ABAJO, IZQ, DER
	};
	
	
	public FabricaPotenciales(Objetivo objetivo, ArrayList<Integer> objetos, Predictor predictor) {
		
		this.objetivo = objetivo;
		this.predictor = predictor;
		// TODO Hay que tener instanciado un Manager de Objetos
		this.objetos = objetos;
		campos = new HashMap<Integer, ArrayList<CampoPotencial>>();
		
	}
	
	public ArrayList<CampoPotencial> getCamposObstaculos() {
		ArrayList<CampoPotencial> camposObstaculos = new ArrayList<CampoPotencial>();
		
		Iterator<Integer> iterObjetos = campos.keySet().iterator();
		Iterator<CampoPotencial> iterCamposObjeto;
		while (iterObjetos.hasNext()) {
			int idObjeto = iterObjetos.next();
			//if (idObjeto != objetivo.getIdObjetivo()) {
				iterCamposObjeto = campos.get(idObjeto).iterator();
				while (iterCamposObjeto.hasNext()) {
					CampoPotencial campoObstaculo = iterCamposObjeto.next();
					camposObstaculos.add(campoObstaculo);
				}
			//} 
		}
		
		return camposObstaculos;
	}
	
	public HashMap<Integer, ArrayList<CampoPotencial>> obtenerCampos(Conector conector) {
		utiles = new Utiles(conector);
		Iterator<Integer> iter = objetos.iterator();
		
		//System.out.println("Se fabricaron los sugientes campos:");
		
		ArrayList<CampoPotencial> camposObjeto = new ArrayList<CampoPotencial>();
		
		if (! objetivo.esObjeto()) {
			camposObjeto.add(new CampoCircularAtractor(objetivo, utiles, predictor));
			campos.put(-2, camposObjeto);
			//System.out.println("-2 -> OBJETIVO PUNTO");
		}
		
		while (iter.hasNext()) {    
			int idObjeto = iter.next();
			camposObjeto = new ArrayList<CampoPotencial>();
			int idObjetivo = objetivo.getIdObjetivo();
			
		    if (objetivo.esObjeto() && idObjeto == idObjetivo) {
		    	if (objetivo.esEjercito()) {
			    	camposObjeto.add(new CampoAtractorObjetivo(objetivo, utiles, predictor));
			    	camposObjeto.add(new CampoTangencialObjetivo(idObjeto, utiles, predictor));
			    	campos.put(idObjeto, camposObjeto);
			    	//System.out.println(idObjeto + " OBJETIVO EJERCITO");
		    	} else {
		    		camposObjeto.add(new CampoCircularAtractor(objetivo, utiles, predictor));
					campos.put(idObjeto, camposObjeto);
					//System.out.println(idObjeto + " OBJETIVO FUERTE");
		    	}
		    } else {
		    	camposObjeto.add(new CampoCircularRepulsor(idObjeto, utiles, predictor));
		    	camposObjeto.add(new CampoTangencialRepulsor(idObjeto, objetivo, utiles, predictor));
		    	campos.put(idObjeto, camposObjeto);
		    	//System.out.println(idObjeto + " OBSTACULO");
		    }
		}
		
		ArrayList<CampoPotencial> camposObstaculos = getCamposObstaculos();
		camposObjeto = new ArrayList<CampoPotencial>();
		camposObjeto.add(new CampoSemiplano(PAREDES.ARRIBA, camposObstaculos, utiles));
		camposObjeto.add(new CampoSemiplano(PAREDES.ABAJO, camposObstaculos, utiles));
		camposObjeto.add(new CampoSemiplano(PAREDES.IZQ, camposObstaculos, utiles));
		camposObjeto.add(new CampoSemiplano(PAREDES.DER, camposObstaculos, utiles));
		campos.put(-1, camposObjeto);
		
		return campos;
	}
	
	public void eliminarCampo(int idObjeto) {
		campos.remove(idObjeto);
		// obtengo el campo del semiplano y le actualizo los campos obstaculos
		campos.remove(-1);
		ArrayList<CampoPotencial> camposObstaculos = getCamposObstaculos();
		ArrayList<CampoPotencial> camposObjeto = new ArrayList<CampoPotencial>();
		camposObjeto = new ArrayList<CampoPotencial>();
		camposObjeto.add(new CampoSemiplano(PAREDES.ARRIBA, camposObstaculos, utiles));
		camposObjeto.add(new CampoSemiplano(PAREDES.ABAJO, camposObstaculos, utiles));
		camposObjeto.add(new CampoSemiplano(PAREDES.IZQ, camposObstaculos, utiles));
		camposObjeto.add(new CampoSemiplano(PAREDES.DER, camposObstaculos, utiles));
		campos.put(-1, camposObjeto);
		
	}
	
}
